<template>
  <div>
    <el-form :model="queryParams" inline>
      <el-form-item label="文件名称" prop="name">
        <el-input v-model.trim="queryParams.fileName" placeholder="输入文件名称"/>
      </el-form-item>
      <el-form-item label="起始时间">
        <el-date-picker
            v-model="timeRange"
            type="datetimerange"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
            format="YYYY-MM-DD HH:mm:ss"
            value-format="YYYY-MM-DD HH:mm:ss"
            date-format="YYYY/MM/DD ddd"
            time-format="A hh:mm:ss"
            @change="handleTimeChange"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="handleSearch">查询</el-button>
      </el-form-item>
    </el-form>
    <div v-if="fileList.length">
      <el-table :data="fileList" border>
        <el-table-column label="文件名称" prop="fileName"/>
        <el-table-column label="文件大小" prop="fileSize">
          <template #default="scope">{{fileSize(scope.row.fileSize)}}</template>
        </el-table-column>
        <el-table-column label="上传时间" prop="createTime"/>
        <el-table-column label="操作">
          <template #default="scope">
            <el-button type="success" size="small" @click="handleDownload(scope.row)">下载</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div v-else>
      <el-empty/>
    </div>
  </div>
</template>
<script setup>
import { saveAs } from 'file-saver';
import { readwrite, getFile } from '@/utils/indexDb';
import {onMounted, ref} from 'vue'
import {
  ElForm,
  ElFormItem,
  ElInput,
  ElDatePicker,
  ElButton,
  ElTable,
  ElTableColumn,
  ElEmpty,
  ElMessage
} from "element-plus";
import {download, getFiles} from "@/api/index.js";

const queryParams = ref({
  fileName: "",
  pageSize: 10,
  pageNumber: 1,
  startTime: '',
  endTime: '',
})
const timeRange = ref(null)
const fileList = ref([])
const handleTimeChange = () => {
  console.log(timeRange.value)
  if (timeRange.value) {
    queryParams.value.startTime = timeRange.value[0]
    queryParams.value.endTime = timeRange.value[1]
  } else {
    queryParams.value.startTime = ''
    queryParams.value.endTime = ''
  }
}
const handleSearch = async () => {
  const resp = await getFiles(queryParams.value)
  console.log('handleSearch',resp)
  if (resp.code === 200) {
    fileList.value = resp.data
  }
}
const handleDownload = (row) => {
  console.log(row)
  downloadFile(row.fileName, row.fileSize, 1024 * 1024)
  // downloadFileSlice(row.fileName, 0, 1024 * 1024)
}

async function downloadFile(fileName, fileSize, chunkSize) {
  const totalChunks = Math.ceil(fileSize / chunkSize);
  for (let i = 0; i < totalChunks; i++) {
    await downloadChunk(fileName, i, chunkSize);
  }
  await mergeChunks(fileName, totalChunks);
}

async function downloadChunk(fileName, chunkIndex, chunkSize) {
  const start = chunkIndex * chunkSize;
  const end = (chunkIndex + 1) * chunkSize - 1;

  const params = { fileName, start, end }
  const response = await download(params);

  if (response.ok) {
    const blob = await response.blob();
    const arrayBuffer = await blob.arrayBuffer();
    const uint8Array = new Uint8Array(arrayBuffer);

    const tx = await readwrite();
    const store = await tx.objectStore('chunks');
    store.put({ id: chunkIndex, data: uint8Array, fileName: fileName });

    return tx.complete;
  } else {
    console.error(`Failed to download chunk ${chunkIndex}`);
  }
}

async function mergeChunks(fileName, totalChunks) {
  let chunks = [];
  for (let i = 0; i < totalChunks; i++) {
    const result = await getFile(i);
    if (result.data.length) chunks.push(result)
  }
  if (totalChunks !== chunks.length) return console.log('文件下载中断···');
  chunks.sort((a, b) => a.id - b.id);
  let totalLength = 0
  for (let i=0; i < chunks.length; i++) {
    totalLength += chunks[i].data.length;
  }
  const mergedArray = new Uint8Array(totalLength);
  // 将每个切片的内容复制到新的 Uint8Array 中
  let offset = 0;
  chunks.forEach(slice => {
    mergedArray.set(slice.data, offset);
    offset += slice.data.length;
  });
  const mergedBlob = new Blob([mergedArray], { type: 'application/octet-stream' });
  saveAs(mergedBlob, fileName);
  console.log('fileName', fileName)
  // 清理数据库
  const clearTx = await readwrite();
  clearTx.objectStore('chunks').clear();
  await clearTx.complete;

  ElMessage.success('文件下载成功!');
}

// 显示文件大小
const fileSize = (val) => {
  const m = 1024 * 1024
  if (val > m) {
    const num = Math.ceil(val / m)
    const numB = Math.ceil(num / 1024)
    if (numB > 1) {
      return `${numB}G`
    } else {
      return `${num}M`
    }
  } else {
    const numC = Math.ceil(val / 1024)
    return `${numC}KB`
  }
}
onMounted(() => {
  handleSearch()
})
</script>
